package com.appshelves.model;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;

import com.appshelves.model.saveable.Saveable;
import com.appshelves.utils.ComponentHelper;
import com.appshelves.utils.Utils;

public class App extends Saveable {
    private String componentNameString; // this field is unchangeable, but it's stored here so I can rebuild AppData whenever I want.
    private int dataID;
    private AppData data;
    private Shelf shelf;

    App(ResolveInfo info) {
        initByInfo(info);
        createData(info);
    }

    public Bitmap getSmallTexture() {
        return data.smallTexture;
    }

    public String getLabel() {
        return data.label;
    }

    public Intent getIntent() {
        return ComponentHelper.prepareIntent(componentNameString);
    }

    public String getPackageName() {
        return ComponentHelper.packageNameByComponentName(componentNameString);
    }

    boolean exists() {
        return getResolveInfo() != null;
    }

    public boolean isSystem() {
        return ComponentHelper.isSystemApp(componentNameString);
    }

    String getComponentNameString() {
        return componentNameString;
    }

    ///

    private ResolveInfo getResolveInfo() {
        return ComponentHelper.resolveInfoByComponentName(componentNameString);
    }

    private void initByInfo(ResolveInfo info) {
        componentNameString = ComponentHelper.makeComponentNameString(info);
    }

    void updateByInfo(ResolveInfo info) {
        initByInfo(info);
        data.initByInfo(info);
    }

    void setShelf(Shelf shelf) {
        this.shelf = shelf;
    }

    Shelf getShelf() {
        return shelf;
    }

    /// .

    void recreateData() {
        createData(getResolveInfo());
    }

    void createData(ResolveInfo info) {
        ModelAPI.getAccessor().addAppDataAndBind(this, info);
    }

    void onDelete() {
        ModelAPI.getAccessor().deleteAppData(dataID);
    }

    void bindData(AppData data) {
        this.data = data;
    }

    void bindData(int dataID) {
        this.dataID = dataID;
    }

    void bindData(AppData data, int dataID) {
        bindData(data);
        bindData(dataID);
    }

    ///

    public int compareByLabel(App app) {
        return getLabel().compareToIgnoreCase(app.getLabel());
    }

    /// Serialization.
    public App() {
    }

    @Override
    protected void initOnLoading(Object arg) {
        shelf = (Shelf) arg;
    }

    @Override
    protected void readFromStream(DataInputStream stream) throws IOException {
        componentNameString = stream.readUTF();
        dataID = stream.readInt();
        ModelAPI.getCreator().bindAppDataIfLoaded(this, dataID);
    }

    @Override
    protected void writeToStream(DataOutputStream stream) throws IOException {
        stream.writeUTF(componentNameString);
        stream.writeInt(dataID);
    }

    /// debug

    protected void log() {
        Utils.log(this, data.label + " shelf: " + shelf);
    }

}
